package Bio::Rambam::Proteomics::Searches::COMET_search;
use Moose;
use namespace::autoclean;
with 'Bio::Rambam::Proteomics::Tools::ENGINE_search';
use Bio::Rambam::Proteomics qw(%ENZYMES %MODS $TEMPLATES);
use Bio::Rambam::Proteomics::Mgf;
use Data::Dumper;
use File::Basename;
use Try::Tiny;

has 'search'	=>	(is=>'rw',	isa=>'Bio::Rambam::Proteomics::Search',	default=>sub{{}}, trigger =>\&_start_comet);

sub _start_comet{
	my $self=shift;
	my $search=$self->search;
	###	Paths
	my $comet_path=$search->engines->comet;
	die "Comet path is not correct.\n You should use the complete path to the executable file.\n" unless -B$comet_path;
	my $comet_out_folder=$search->folder."/comet";	#only works for linux
	my $comet_out_file = basename($search->input_file);
	$comet_out_file =$comet_out_folder.'/'.$comet_out_file;
	$comet_out_file=~s/\.mgf//;
	mkdir $comet_out_folder unless -d$comet_out_folder;
	my $comet_conf_file=$comet_out_folder.'/'."comet_conf.txt";
	
	############################################################	Comet Arguments
	my %replacements;
	$replacements{database}=$search->database;
	$replacements{peptide_tol}=$search->peptide_tol;
	$replacements{pep_tol_units}=0 if $search->pep_tol_units eq 'Da';
	$replacements{pep_tol_units}=2 if $search->pep_tol_units eq 'ppm';
	$replacements{fragment_tol}=2*$search->fragment_tol;	### Check this: the bin equals +-fragment tolerance?
	$replacements{threads}=$search->threads;
	$replacements{enzyme}=$ENZYMES{$search->enzyme}{'Comet'};
	$replacements{miss_cleavages}=$search->miss_cleavages;
	$replacements{top_peptide_charge}=$search->top_peptide_charge;
	
	$replacements{use_A_ions}=0;
	$replacements{use_B_ions}=0;
	$replacements{use_C_ions}=0;
	$replacements{use_X_ions}=0;
	$replacements{use_Y_ions}=0;
	$replacements{use_Z_ions}=0;
	if($search->fragmentation eq 'CID'){
		$replacements{use_B_ions}=1;
		$replacements{use_Y_ions}=1;
	}
	elsif(($search->fragmentation eq 'ETD') or ($search->fragmentation eq 'ECD')){
		$replacements{use_C_ions}=1;
		$replacements{use_Y_ions}=1;
		$replacements{use_Z_ions}=1;
	}
	
	#############	Modifications
	##	Variable mods
	$replacements{variable_C_terminus}="0.0";
	$replacements{variable_N_terminus}="0.0";
	for my $i(1..6){
		$replacements{'variable_mod'.$i}="0.0 X 0 3";
	}
	my $num_var_mos_in_aa=0;
	foreach(split /\,/,$search->variable_mods){
		my ($mod,$res)=split /\@/;
		if(length($res)==1){
			$num_var_mos_in_aa++;
			die "Comet maximum number of variable modifications is 6\n" if $num_var_mos_in_aa>6;
			$replacements{'variable_mod'.$num_var_mos_in_aa}="$MODS{$mod}{'mass'} $res 0 3";
		}
		$replacements{variable_C_terminus}=$MODS{$mod}{'mass'} if $res eq 'Ct';
		$replacements{variable_N_terminus}=$MODS{$mod}{'mass'} if $res eq 'Nt';
	}
	
	##	Fixed mods
	$replacements{fixed_C_terminus}="0.0";
	$replacements{fixed_N_terminus}="0.0";
	$replacements{add_G_glycine}="0.0";
	$replacements{add_A_alanine}="0.0";
	$replacements{add_S_serine}="0.0";
	$replacements{add_P_proline}="0.0";
	$replacements{add_V_valine}="0.0";
	$replacements{add_T_threonine}="0.0";
	$replacements{add_C_cysteine}="0.0";
	$replacements{add_L_leucine}="0.0";
	$replacements{add_I_isoleucine}="0.0";
	$replacements{add_N_asparagine}="0.0";
	$replacements{add_D_aspartic_acid}="0.0";
	$replacements{add_Q_glutamine}="0.0";
	$replacements{add_K_lysine}="0.0";
	$replacements{add_E_glutamic_acid}="0.0";
	$replacements{add_M_methionine}="0.0";
	$replacements{add_O_ornithine}="0.0";
	$replacements{add_H_histidine}="0.0";
	$replacements{add_F_phenylalanine}="0.0";
	$replacements{add_R_arginine}="0.0";
	$replacements{add_Y_tyrosine}="0.0";
	$replacements{add_W_tryptophan}="0.0";
	
	foreach(split /\,/,$search->fixed_mods){
		my ($mod,$res)=split /\@/;
		if(length($res)==1){
			foreach my $rep(keys %replacements){
				if($rep=~/^add\_([A-Z])\_(.+)/){
					$replacements{"add_".$1."_".$2}=$MODS{$mod}{'mass'} if $1 eq $res;
				}
			}
			$replacements{'variable_mod'.$num_var_mos_in_aa}="$MODS{$mod}{'mass'} $res 0 3";
		}
		$replacements{fixed_C_terminus}=$MODS{$mod}{'mass'} if $res eq 'Ct';
		$replacements{fixed_N_terminus}=$MODS{$mod}{'mass'} if $res eq 'Nt';
	}
	
	#######
	my $comet_conf_template=$TEMPLATES."comet.txt";
	my $comet_conf_text=template($comet_conf_template,\%replacements);
	open my $output,">",$comet_conf_file;
	print $output $comet_conf_text;
	close $output;
	
	my $command="$comet_path -P$comet_conf_file -N$comet_out_file";
	#print $command,"\n";
	my $mgf_input_file=Bio::Rambam::Proteomics::Mgf->new(file=>$search->input_file);
	my $ms2_file=$mgf_input_file->convert_to_ms2(output_folder=>$comet_out_folder);
	
	$command.=" ".$ms2_file->file;
	
	run_command($command,$self);
	$self->output_file ($comet_out_file.".pep.xml");
	
}



__PACKAGE__->meta->make_immutable;